/*
  This file is part of JCM.

  JCM is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  JCM is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with JCM.  If not, see <http://www.gnu.org/licenses/>.
*/
import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 * Classe para aumentar a responsividade durante a digitação colorindo o
 * texto conforme compatibilidade com um padrão estabelecido via expressão
 * regular.
 *
 * Nota: Evita-se uso do método "parser" do formatador interno que
 *       extrai números de textos mesmo que parcialmente inválidos.
*/
public class JTextFieldDoubleEditor extends JFormattedTextField implements CaretListener, FocusListener
{
  /**
   * Construtor invocando a superclasse e montando especialidades.
   *
   * @param formatter Formatador de números reais.
   * @param regex Expressão regular para qualificar o texto digitado.
  */
  public JTextFieldDoubleEditor(DecimalFormat formatter, String regex)
  {
    super(formatter);
    // cria o analista via expressão regular
    matcher = Pattern.compile(regex).matcher("");
    // adiciona observadores de eventos
    addCaretListener(this);
    addFocusListener(this);
  }

  /**
   * Construtor usando a expressão regular padrão.
   *
   * @param formatter Formatador de números reais.
  */
  public JTextFieldDoubleEditor(DecimalFormat formatter)
  {
    this(formatter, defaultDoublePattern);
  }

  /**
   * Construtor usando formatador e expressão regular defaults.
  */
  public JTextFieldDoubleEditor()
  {
    this(NumberFormatFactory.getDecimalFormat(), defaultDoublePattern);
  }

  /**
   * Método responsivo a observações de eventos do cursor.
   * A cada movimento do cursor devido a digitação, o texto é colorido
   * conforme aderência ao padrão imposto: <b>Vermelho</b> se está
   * incompleto ou inadequado e <b>Verde</b> em caso contrário.
   *
   * @param e O evento de cursor.
  */
  public void caretUpdate(CaretEvent e)
  {
    // checa se o evento ocorre quando o componente têm foco
    if (hasFocus()) {
      // checa se o texto adere ao padrão
      if (matcher.reset(getText()).matches())
      {
        setForeground(GREEN);
      } else {
        setForeground(Color.RED);
      }
    }
  }

  /**
   * Método responsivo a observações do evento foco obtido.
   *
   * @param e O evento de foco obtido.
  */
  public void focusGained(FocusEvent e)
  {
  }

  /**
   * Método responsivo a observações do evento perda de foco
   * alterando a cor do texto para Preto.
   *
   * @param e O evento de perda de foco.
  */
  public void focusLost(FocusEvent e)
  {
    // evita problemas de sincronia devido a concorrência de eventos
    EventQueue.invokeLater(new Runnable() {
      public void run() { setForeground(Color.BLACK); }
    });
  }

  /** Analista de textos via expressão regular. */
  private Matcher matcher;

  /** Padrão de expressão regular para números reais. */
  private static final String defaultDoublePattern = "\\-?\\d{1,3}(?:\\.\\d{3})*,\\d\\d+";

  private static final Color GREEN = new Color(0, 150, 0);

  private static final long serialVersionUID = 6671497050547554834L;
}